//////////////////////////////////////////////////////////////////////////////////
//
// ActionScript 3.0 Common Library (MIT License)
// Copyright (c) 2009 AS3CommonCode | Tony Birleffi | http://www.mosaiceye.com
// 
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
// 
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
// 
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
//
//////////////////////////////////////////////////////////////////////////////////

package org.as3commoncode.net.loader 
{
	import flash.errors.IllegalOperationError;	
	import flash.display.LoaderInfo;
    import flash.display.Loader;
    import flash.events.Event;
    import flash.events.HTTPStatusEvent;
	import flash.events.IEventDispatcher;
    import flash.events.IOErrorEvent;
    import flash.events.ProgressEvent;
    import flash.net.URLRequest;
	import flash.text.Font;
	
	import org.as3commoncode.net.loader.AbstractLoader;
	import org.as3commoncode.events.FontLoaderEvent;		/**
	 * Loads a SWF, with an embedded font-family and registers it to the global font list. 
	 * It's a child of this Loader object. And extends the AbstractLoader class.
	 * 
	 * @example
	 * <listing>
	 * var fl:FontLoader = new FontLoader("swf/emArial.swf");
	 * fl.addEventListener(FontLoaderEvent.COMPLETE, onFontComplete);
	 * fl.registerFont("emArial");
	 * fl.load();
	 * </listing>
	 * 
	 * @see org.as3commoncode.net.loader.AbstractLoader;
	 * @see org.as3commoncode.events.FontLoaderEvent;
	 * 
	 * @author Tony Birleffi
	 */
    public class FontLoader extends AbstractLoader 
	{
		/** Instance of the loader class. */
		private var loader:Loader;
		
		/** Defines the list of font names to embbed. */
		private var fontList:Array = [];
		
		/** Reference to the embedded font loaded in by this class. */
		private var embeddedFont:Font = null;
        
		/**
		 * Handles the initial setup.
		 * 
		 * @param url		string path to the media file.
		 */
		public function FontLoader(url:String = null) 
		{
			// Call the super.
		    super(new URLRequest(url));
		    
			// Make an instance of the loader class.
		    this.loader = new Loader();
		}
		
		/**
		 * Register each font in.
		 * 
		 * @param fontName		pass the font name in.
		 */
		public function registerFont(fontName:String):void
		{
			// Push.
			this.fontList.push(fontName);
		}
		
		/**
		 * Loads a swf or image file from the specified url, if you specified it 
		 * already in the constructor you can omit it.
		 * 
		 * @param urlRequest		an url request.
		 */
		public override function load(urlRequest:URLRequest = null):void 
		{
			// You can also setup the URL request here as well.
		    if(urlRequest != null) request = urlRequest;
		
			// Add the listeners.
			configureListeners(this.loader.contentLoaderInfo);
		
			// Start the load.
		    this.loader.load(request);
		}
	
		/**
		 * Stops the download of the file.
		 */
		public override function stop():void 
		{
			// If the load is running, close the load.
            if(running)
			{
				try { 
					this.loader.close();
				} catch(e:Error) {
					throw new IllegalOperationError("The loader never closed.");
				}
            }
			
			// Stop the load.
            running = false;
		    this.loader.unload();
		}
		
		/**
		 * Register's the font after being loaded in.
		 * 
		 * @param event			the event object.
		 */
		private function registerFontList(event:Event):void
		{
			// Set the running.
			running = false;
			
			// Define the font list length.
			var length:Number = fontList.length;
		
			// Rip through the font list and register each font.
			for(var i:Number = 0; i < length; ++i)
			{
				// Define the current font name.
				var fontName:String = fontList[ i ];
				
				// Check for no empty strings.
				if(fontName.length > 0)
				{
					// Define the current font class.
					var embedFontClass:Class = info.applicationDomain.getDefinition(fontName) as Class;
					
					// Register the font class to the global font list.
					Font.registerFont(embedFontClass);
					
					// Define the embedded font.
					var embedFontsArray:Array = Font.enumerateFonts(false);
					embeddedFont = embedFontsArray[ 0 ];
				}
			}
			
			// Dispatch an event.
			dispatchEvent(new FontLoaderEvent(FontLoaderEvent.COMPLETE, this.fontList));
		}
		
		/**
		 * Simply delegates the event.
		 * 
		 * @param event			the event object.
		 */
		private function delegate(event:Event):void 
		{
		    dispatchEvent(event);
		}
	
		/**
		 * Simply configures the event listeners.
		 * 
		 * @param dispath		the event dispatcher interface.
		 */
		private function configureListeners(dispath:IEventDispatcher):void
		{
			dispath.addEventListener(Event.COMPLETE, registerFontList);
			dispath.addEventListener(HTTPStatusEvent.HTTP_STATUS, delegate);
			dispath.addEventListener(Event.INIT, delegate);
			dispath.addEventListener(IOErrorEvent.IO_ERROR, delegate);
			dispath.addEventListener(Event.OPEN, delegate);
			dispath.addEventListener(ProgressEvent.PROGRESS, delegate);
			dispath.addEventListener(Event.UNLOAD, delegate);
		}
		
		/**
		 * Returns the loader instance that has loaded the swf/image from the given url.
		 * 
		 * @return Loader.
		 */
		public function get file():Loader 
		{
		    return this.loader;
		}
		
		/**
		 * Returns the loader info for adding listeners to.
		 * 
		 * @return LoaderInfo.
		 */
		public function get info():LoaderInfo
		{
			return this.loader.contentLoaderInfo;
		}
    }
}